﻿using System;
using System.Net;
using System.Net.Cache;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Security;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using XQ.Framework.core;
using XQ.Framework.io;

namespace XQ.Framework.net
{
    public class HttpClient
    {

        //浏览器列表
        public static readonly string[] BROWSER_LIST = new string[] { "ie", "chrome", "mozilla", "netscape", "firefox", "opera", "konqueror" };
        //搜索引擎列表
        public static readonly string[] SEARCH_ENGINE_LIST = new string[] { "baidu", "google", "360", "sogou", "bing", "msn", "sohu", "163", "yahoo" };

        public static void HttpRequestHandler(
            string url,
            Dictionary<string, string> param,
            CookieCollection cookies,
            string method,
            int timeout,
            Func<Stream, Encoding, bool> OnHandler)
        {
            url = ConvertHelper.getString(url);
            method = ConvertHelper.getString(method).ToUpper();
            if (!(url.ToLower().StartsWith("http://") || url.ToLower().StartsWith("https://")))
            {
                url = "http://" + url;
            }
            HttpWebRequest http_request = null;
            HttpWebResponse http_response = null;
            Stream stream = null;
            try
            {
                //连接到目标网页
                http_request = (HttpWebRequest)WebRequest.Create(url);
                //发送X_FORWARDED_FOR头(若是用取源IP的方式，可以用这个来造假IP,对日志的记录无效)
                http_request.Headers.Add("X_FORWARDED_FOR", "101.0.0.11");
                http_request.Timeout = timeout;//10s请求超时
                http_request.Method = method;
                http_request.KeepAlive = true;
                http_request.AllowAutoRedirect = true;
                http_request.ContentType = "application/x-www-form-urlencoded";
                http_request.AllowAutoRedirect = true;
                http_request.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
                http_request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";

                if (cookies != null)
                {
                    http_request.CookieContainer = new CookieContainer();
                    http_request.CookieContainer.Add(cookies);
                }
                //如果是post并且有参数
                if (method != "GET" && param != null)
                {
                    StringBuilder post_data = new StringBuilder();
                    int i = 0;
                    foreach (string key in param.Keys)
                    {
                        if (key == null || param[key] == null) { continue; }
                        post_data.Append(string.Format((i > 0 ? "&" : "") + "{0}={1}", key, param[key]));
                        ++i;
                    }
                    byte[] data = Encoding.ASCII.GetBytes(post_data.ToString());
                    stream = http_request.GetRequestStream();
                    stream.Write(data, 0, data.Length);
                    //stream.Close();
                    IOHelper.closeStream(stream);
                }
                http_response = (HttpWebResponse)http_request.GetResponse();
                if (http_response.StatusCode != HttpStatusCode.OK)
                {
                    return;
                }
                //采用流读取，并确定编码方式
                stream = http_response.GetResponseStream();
                if (OnHandler == null)
                {
                    return;
                }
                string charset = ConvertHelper.getString(http_response.CharacterSet).Trim().ToLower();
                Encoding encode = null;
                try
                {
                    if (charset == "iso-8859-1")
                    {
                        encode = Encoding.GetEncoding("gbk");
                    }
                    if (ValidateHelper.IsPlumpString(charset))
                    {
                        encode = Encoding.GetEncoding(charset);
                    }
                    else
                    {
                        encode = Encoding.UTF8;
                    }
                    encode = Encoding.UTF8;
                }
                catch
                {
                    encode = Encoding.UTF8;
                }
                OnHandler.Invoke(stream, encode);
            }
            catch (Exception e) //遇到错误，打印错误
            {
                //
            }
            finally
            {
                IOHelper.closeStream(stream);
                if (http_response != null) { http_response.Close(); }
            }
        }

        public static byte[] GetHttpBytes(string url, Dictionary<string, string> param,
            CookieCollection cookies, string method, int timeout)
        {
            byte[] b = null;
            HttpRequestHandler(url, param, cookies, method, timeout,
                delegate(Stream stream, Encoding encode)
                {
                    b = ConvertHelper.StreamToBytes(stream);
                    return true;
                });

            return b;
        }

        public static string GetUrlContent(string url, Dictionary<string, string> param,
            CookieCollection cookies, string method, int timeout, Encoding encoding)
        {
            try
            {
                byte[] b = GetHttpBytes(url, param, cookies, method, timeout);
                if (!ValidateHelper.IsPlumpArray(b)) { return string.Empty; }
                return encoding.GetString(b, 0, b.Length);
            }
            catch (Exception e)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="param"></param>
        /// <param name="cookies"></param>
        /// <param name="method"></param>
        /// <param name="timeout"></param>
        /// <param name="charset"></param>
        /// <returns></returns>
        public static string GetUrlContent(string url, Dictionary<string, string> param,
            CookieCollection cookies, string method, int timeout, string charset)
        {
            MemoryStream ms = null;
            StreamReader stream_reader = null;
            try
            {
                byte[] b = GetHttpBytes(url, param, cookies, method, timeout);
                if (!ValidateHelper.IsPlumpArray(b)) { return string.Empty; }
                ms = new MemoryStream(b);
                stream_reader = new StreamReader(ms,
                    ValidateHelper.IsPlumpString(charset) ?
                    System.Text.Encoding.GetEncoding(charset) : System.Text.Encoding.Default);

                string temp_string = null;
                StringBuilder html = new StringBuilder();
                //读取
                while (true)
                {
                    if ((temp_string = stream_reader.ReadLine()) == null)
                    {
                        break;
                    }
                    html.Append(temp_string);
                }
                return html.ToString();
            }
            catch (Exception e) //遇到错误，打印错误
            {
                return string.Empty;
            }
            finally
            {
                IOHelper.closeStreamReader(stream_reader);
                IOHelper.closeStream(ms);
            }
        }

    }
}